package com.itheima.stock.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.stock.common.ResponseCode;
import com.itheima.stock.constants.SysUserConstant;
import com.itheima.stock.ex.CustomerException;
import com.itheima.stock.mapper.SysUserMapper;
import com.itheima.stock.pojo.SysUser;
import com.itheima.stock.service.SysUserService;
import com.itheima.stock.utils.IdWorker;
import com.itheima.stock.vo.req.LoginReqVo;
import com.itheima.stock.vo.req.UserPageReqVo;
import com.itheima.stock.vo.resp.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
* @author 10937
* @description 针对表【sys_user(用户表)】的数据库操作Service实现
* @createDate 2022-12-05 20:59:54
*/
@Service
public class SysUserServiceImpl implements SysUserService{
    private String CAPTCHA_REDIS_PREFIX = "captcha:";
    private Integer CAPTCHA_EXPIRE_TIME = 60;
    private Integer CODE_LONG = 4;
    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    IdWorker idWorker;

    @Override
    public R<LoginRespVo> login(LoginReqVo vo) throws CustomerException {
        //判断验证码是否正确
        String redisKey = CAPTCHA_REDIS_PREFIX + vo.getRkey();
        try {
            Object o = redisTemplate.opsForValue().get(redisKey);
            if (!vo.getCode().equals(o)) {
                throw new CustomerException(ResponseCode.SYSTEM_VERIFY_CODE_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.error(ResponseCode.SYSTEM_VERIFY_CODE_ERROR.getMessage());
        }

        try {
            redisTemplate.delete(redisKey);
        } catch (Exception e) {
            e.printStackTrace();
        }

        SysUser dbUser = sysUserMapper.findByUserName(vo.getUsername());

        if (Objects.isNull(dbUser)) {
            throw new CustomerException(ResponseCode.SYSTEM_PASSWORD_ERROR);
        }
        //判断用户是否被禁用
        if (SysUserConstant.USER_STATUS_LOCK.equals(dbUser.getStatus())) {
            throw new CustomerException(ResponseCode.SYSTEM_USERNAME_LOCKED);
        }
        //判断用户是否被删除
        if (SysUserConstant.USER_DELETE.equals(dbUser.getDeleted())) {
            throw new CustomerException(ResponseCode.SYSTEM_USERNAME_DISABLED);
        }

        boolean matches = passwordEncoder.matches(vo.getPassword(), dbUser.getPassword());
        //判断密码是否正确
        if (!matches) {
            throw new CustomerException(ResponseCode.SYSTEM_PASSWORD_ERROR);
        }

        LoginRespVo loginRespVo = new LoginRespVo(dbUser);

        return R.ok(loginRespVo);
    }

    @Override
    public R<CaptchaRespVo> generateCaptcha() {
        try {
            //生成验证码code
            String code = RandomStringUtils.randomNumeric(CODE_LONG);
            //生成验证码唯一id
            long redisId = idWorker.nextId();
            //验证码存入redis
            String redisKey = CAPTCHA_REDIS_PREFIX + redisId;

            redisTemplate.opsForValue().set(redisKey, code, CAPTCHA_EXPIRE_TIME, TimeUnit.SECONDS);
            //填充数据返回
            CaptchaRespVo captchaRespVo = CaptchaRespVo.builder().code(code).rkey(String.valueOf(redisId)).build();
            return R.ok(captchaRespVo);
        } catch (Exception e) {
            e.printStackTrace();
            return R.error(ResponseCode.SYSTEM_ERROR.getMessage());
        }
    }

    @Override
    public R<PageResult<UserPageRespVo>> findPageVo(UserPageReqVo reqVo) throws CustomerException {
        if (reqVo==null) {
            throw new CustomerException(ResponseCode.DATA_ERROR);
        }
        if (reqVo.getPageNum() == null
            || reqVo.getPageSize() == null) {
            throw new CustomerException(ResponseCode.DATA_ERROR);
        }

        PageHelper.startPage(reqVo.getPageNum(), reqVo.getPageSize());
        List<UserPageRespVo> dbSysUsers = sysUserMapper.selectAllByPageVo(reqVo);
        PageInfo<UserPageRespVo> sysUserPageInfo = new PageInfo<>(dbSysUsers);
        PageResult<UserPageRespVo> pageResult = new PageResult<>(sysUserPageInfo);

        return R.ok(pageResult);
    }
}




